﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BDPAutodetect.Device;
using BDPAutodetect.Hardware;
using BDPAutodetect.Models;

namespace BDPAutodetect.Mgrcore
{
    /// <summary>
    /// 检测任务管理
    /// </summary>
    public partial class DetectJobManager : BaseManager
    {
        /// <summary>
        /// 条码扫描辅助实例
        /// </summary>
        protected BarcodeHookEx BarcodeHook { get; set; }
        /// <summary>
        /// 指标设备协议管理实例
        /// </summary>
        protected TargetSlaveManager TargetSlaveMgr { get; set; }
        /// <summary>
        /// 检测记录管理实例
        /// </summary>
        protected DetectRecordManager DetectRecordMgr { get; set; }
        /// <summary>
        /// 系统参数管理实例
        /// </summary>
        protected SettingSystemManager SettingSystemMgr { get; set; }
        /// <summary>
        /// 工位检测任务集
        /// </summary>
        public List<DetectJobStation> StationDetects { get; protected set; }
        /// <summary>
        /// 扫码枪是否启用状态-参数实例
        /// </summary>
        public MSettingSystem? SettingEnableBarcode { get; protected set; }
        /// <summary>
        /// 扫码枪是否启用状态
        /// </summary>
        public bool IsEnableBarcode => this.SettingEnableBarcode?.GetData(true) ?? true;
        /// <summary>
        /// 是否有效存在指标检测信息
        /// </summary>
        public bool IsValidDetect => this.StationDetects != null && this.StationDetects.Count > 0;

        /// <summary>
        /// 构造函数
        /// </summary>
        public DetectJobManager(TargetSlaveManager argTargetSlaveManager, DetectRecordManager detectRecordManager, SettingSystemManager argSettingSystemManager, BarcodeHookEx argBarcodeHook)
            : base("检测任务管理中心")
        {
            this.StationDetects = new List<DetectJobStation>();
            this.TargetSlaveMgr = argTargetSlaveManager;
            this.DetectRecordMgr = detectRecordManager;
            this.SettingSystemMgr = argSettingSystemManager;
            this.BarcodeHook = argBarcodeHook;
            this.BarcodeHook.BarcodeHookEvent += CallbackBarcodeHookEvent;            
        }

        /// <summary>
        /// 初始化工位检测数据
        /// </summary>
        public override async Task Initialize()
        {
            //获取系统参数设置，扫码枪启用状态
            this.SettingEnableBarcode = this.SettingSystemMgr.GetSettingTypeData(SettingType.EnableBarcode);
            if (!this.TargetSlaveMgr.IsValidCustomer) return;
            //启动条码扫描
            this.BarcodeHook.Start(this.SettingEnableBarcode);
            //初始化工位检测任务
            var resultTask = Task.Run(() =>
            {
                var stations = this.TargetSlaveMgr.GetStations();
                //循环添加到集合
                foreach (var stationItem in stations.OrderBy(v => v.ID))
                {
                    if (stationItem == null || stationItem.ID < 1) continue;
                    //测试 工位1
                    //if (stationItem.StationType != DeviceStationType.Station1) continue;
                    var totalData = this.DetectRecordMgr.GetDetectTotalData(stationItem.StationType);
                    MStationDetectDto stationDetect = new MStationDetectDto(stationItem, totalData, this.TargetSlaveMgr.GetTargetDetects(), this.SettingEnableBarcode);
                    this.StationDetects.Add(new DetectJobStation(stationItem.StationType, stationDetect));
                }
                foreach (var item in this.StationDetects)
                {
                    item.Initialize();
                }
            });
            await resultTask.ConfigureAwait(false);
        }

        /// <summary>
        /// 设置条码，并开始检测
        /// </summary>
        public bool SetBarcode(string argBarcode)
        {
            if (!this.IsValidDetect || string.IsNullOrEmpty(argBarcode)) return false;
            //检测条是否已经存在检测中
            foreach (var item in this.StationDetects)
            {
                if (item.IsExistsBarcode(argBarcode)) return false;
            }
            //获取已启动检测工位
            var startDetects = this.StationDetects.Where(v => v.DetectStatus == DetectJobStatus.Startup);
            if (startDetects == null || startDetects.Count() <= 0) return false;
            //默认按顺序第一个
            var startDetect = startDetects.FirstOrDefault();
            startDetect?.SetBarcode(argBarcode);
            return true;
        }

        /// <summary>
        /// 设置参数
        /// </summary>
        /// <param name="argStationType">工位类型</param>
        /// <param name="argParameterData">参数数据</param>
        public void SetParameter(DeviceStationType argStationType, MParameterData? argParameterData)
        {
            var stationDetect = this.GetStationDetectData(argStationType);
            if (stationDetect == null) return;
            stationDetect.ParameterData = argParameterData;
        }

        /// <summary>
        /// 获取工位参数数据
        /// </summary>
        /// <param name="argStationType">工位类型</param>
        /// <returns></returns>
        public DetectJobStation? GetStationJob(DeviceStationType argStationType)
        {
            if (!this.IsValidDetect || argStationType == DeviceStationType.None) return default;
            return this.StationDetects.FirstOrDefault(v => v.StationType == argStationType);
        }

        /// <summary>
        /// 获取工位指标检测信息
        /// </summary>
        /// <param name="argStationType">工位类型</param>
        /// <returns></returns>
        public MStationDetectDto? GetStationDetectData(DeviceStationType argStationType)
        {
            var detectJob = this.GetStationJob(argStationType);
            return detectJob?.DetectData ?? null;
        }

        /// <summary>
        /// 获取工位参数数据
        /// </summary>
        /// <param name="argStationType">工位类型</param>
        /// <returns></returns>
        public MParameterData? GetStationDetectParameter(DeviceStationType argStationType)
        {
            var stationDetect = this.GetStationDetectData(argStationType);
            return stationDetect?.ParameterData ?? default;
        }

        /// <summary>
        /// 回调接收条码扫描事件函数
        /// </summary>
        /// <param name="argBarcodeMsg">条码消息</param>
        protected void CallbackBarcodeHookEvent(BarcodeMessage argBarcodeMsg)
        {
            this.SetBarcode(argBarcodeMsg.Barcode);
        }
    }
}
